home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xvmines-.0
/
xvmines-
/
xvmines-1.0
/
xvmines.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-20
|
15KB
|
580 lines
#include <math.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/frame.h>
#include <xview/canvas.h>
#include <xview/notice.h>
#include <xview/cms.h>
#include <xview/font.h>
#include "xvmines.h"
#include "version.h"
#include "xvmines.icons"
#define CREATE_ICON(bits,width,height) \
XCreateBitmapFromData(display,RootWindow(display,screen),\
bits,width,height)
/* #define DEBUG */
#ifndef lint
static char sccsid[] = "@(#)xvmines,v0.2 by Manolis Lourakis.";
static char Copyright[] = "(c) 1992 Manolis Lourakis.\n";
static char Mail[] = "lourakis@csd.uch.gr";
#endif
#define T_FONT_NAME "-adobe-*-*-*-normal-*-12-*-*-*-*-*-*-*"
extern char *optarg;
extern int optind;
#ifdef __STDC__
void canvas_event_proc(Xv_Window, Event *);
void canvas_repaint_proc(void);
void finish(char *);
void print_string(char *, int, int, int);
#else
void canvas_event_proc();
void canvas_repaint_proc();
void finish();
void print_string();
#endif
Display *display;
Visual *visual;
int screen;
GC def_gc;
Frame frame;
Panel panel1;
Panel_item opt;
Canvas canvas, msg_canvas;
Window dr_win;
Pixmap pmap, icons[NUM_ICONS];
cell *Cells;
char buff[256];
Notify_func active_func = NOTIFY_FUNC_NULL;
int quit_proc(), init(), restart(), hide_cmd_frame();
#ifdef __STDC__
int adj_mine_num(Panel_item, Event *), adj_size(Panel_item, Event *),
show_cmd_frame(Menu, Menu_item);
int place_tiles(int, int, int),
mark_tile(int, int),
open_tile(int, int),
auto_open(int, int);
Frame create_cmd_frame(Frame, char *, int (*notifier) ());
#else
int adj_mine_num(), adj_size(), show_cmd_frame();
int place_tiles(), mark_tile(), open_tile(), auto_open();
Frame create_cmd_frame();
#endif
int mines_2_go, closed_tiles, playing, first, checks, secs;
int first_tile;
int width = HORIZ_CELLS, height = VERT_CELLS, mines = NUM_MINES,
quantum = QUANTUM;
struct itimerval timer;
#ifdef __STDC__
int
main(int argc, char *argv[])
#else
int
main(argc, argv)
int argc;
char *argv[];
#endif
{
int ret, tmp;
register int i, j;
int errflag = 0, badparam = 0, gc;
XWMHints wm_hints;
XClassHint class_hints;
XTextProperty windowName, iconName;
char *window_name = version_string;
char *icon_name = version_string;
Menu menu;
Menu_item entry1, entry2, entry3;
Frame aux_fr;
Cms cms;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
while ((gc = getopt(argc, argv, "w:h:m:q:")) != EOF)
switch (gc) {
case 'w':
tmp = atoi(optarg);
if (tmp > 0 && tmp <= MAX_WIDTH)
width = tmp;
else
badparam++;
break;
case 'h':
tmp = atoi(optarg);
if (tmp > 0 && tmp <= MAX_HEIGHT)
height = tmp;
else
badparam++;
break;
case 'm':
tmp = atoi(optarg);
if (tmp > 0)
mines = tmp;
else
badparam++;
break;
case 'q':
tmp = atoi(optarg);
if (tmp > 0)
quantum = tmp;
else
badparam++;
break;
case '?':
errflag++;
break;
}
if (badparam) {
fprintf(stderr,
"xvmines: Bad argument(s).\n");
exit(1);
}
if (errflag) {
fprintf(stderr,
"Usage: xvmines [-w width] [-h height] [-m mines] [-q quantum]\n");
exit(1);
}
if (mines > width * height) {
fprintf(stderr, "xvmines: Too many mines, using defaults\n");
width = HORIZ_CELLS;
height = VERT_CELLS;
mines = NUM_MINES;
}
Cells = (cell *) malloc(width * height * sizeof(cell));
if (Cells == NULL) {
fprintf(stderr, "xvmines: malloc failed\n");
exit(1);
}
cms = xv_create(NULL, CMS,
CMS_SIZE, CMS_CONTROL_COLORS + 1,
CMS_CONTROL_CMS, True,
CMS_NAMED_COLORS, "red", NULL,
NULL);
frame = (Frame) xv_create(NULL, FRAME,
FRAME_LABEL, version_string,
XV_WIDTH, width * IC_WIDTH,
WIN_CMS, cms,
FRAME_SHOW_FOOTER, TRUE,
FRAME_LEFT_FOOTER, "",
FRAME_RIGHT_FOOTER, "",
NULL);
display = (Display *) xv_get(frame, XV_DISPLAY);
screen = DefaultScreen(display);
visual = DefaultVisual(display, screen);
def_gc = DefaultGC(display, screen);
panel1 = xv_create(frame, PANEL,
PANEL_LAYOUT, PANEL_HORIZONTAL,
NULL);
xv_create(panel1, PANEL_BUTTON,
PANEL_LABEL_STRING, "Quit",
PANEL_NOTIFY_PROC, quit_proc,
NULL);
xv_create(panel1, PANEL_BUTTON,
PANEL_LABEL_STRING, "New",
PANEL_NOTIFY_PROC, restart,
NULL);
aux_fr = create_cmd_frame(frame, "New number of mines: ", adj_mine_num);
entry1 = (Menu_item) xv_create((unsigned long) NULL, MENUITEM,
MENU_STRING, "Mines",
XV_KEY_DATA, KEY, aux_fr,
MENU_NOTIFY_PROC, show_cmd_frame,
NULL);
aux_fr = create_cmd_frame(frame, "New dimensions (wxh): ", adj_size);
entry2 = (Menu_item) xv_create((unsigned long) NULL, MENUITEM,
MENU_STRING, "Dimensions",
XV_KEY_DATA, KEY, aux_fr,
MENU_NOTIFY_PROC, show_cmd_frame,
NULL);
menu = (Menu) xv_create((unsigned long) NULL, MENU,
MENU_APPEND_ITEM, entry1,
MENU_APPEND_ITEM, entry2,
NULL);
opt = xv_create(panel1, PANEL_BUTTON,
PANEL_LABEL_STRING, "Options",
PANEL_ITEM_MENU, menu,
NULL);
window_fit_height(panel1);
msg_canvas = xv_create(frame, CANVAS,
XV_HEIGHT, MSG_CANVAS_HEIGHT,
NULL);
sprintf(buff, "Mines: %d\n", mines);
xv_set(frame, FRAME_LEFT_FOOTER, buff, NULL);
sprintf(buff, "Checks: 0");
xv_set(frame, FRAME_RIGHT_FOOTER, buff, NULL);
/* window_fit_height(panel2); */
canvas = xv_create(frame, CANVAS,
CANVAS_X_PAINT_WINDOW, TRUE,
XV_WIDTH, IC_WIDTH * width,
XV_HEIGHT, IC_HEIGHT * height,
WIN_EVENT_PROC, canvas_event_proc,
CANVAS_REPAINT_PROC, canvas_repaint_proc,
NULL);
xv_set(canvas_paint_window(canvas),
WIN_CONSUME_X_EVENT_MASK,
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask,
WIN_EVENT_PROC, canvas_event_proc,
NULL);
dr_win = xv_get(canvas_paint_window(canvas), XV_XID);
pmap = XCreatePixmap(display, dr_win, IC_WIDTH * width,
IC_HEIGHT * height, DefaultDepth(display, screen));
icons[EMPTY] = CREATE_ICON(empty_bits, empty_width, empty_height);
icons[ONE] = CREATE_ICON(one_bits, one_width, one_height);
icons[TWO] = CREATE_ICON(two_bits, two_width, two_height);
icons[THREE] = CREATE_ICON(three_bits, three_width, three_height);
icons[FOUR] = CREATE_ICON(four_bits, four_width, four_height);
icons[FIVE] = CREATE_ICON(five_bits, five_width, five_height);
icons[SIX] = CREATE_ICON(six_bits, six_width, six_height);
icons[SEVEN] = CREATE_ICON(seven_bits, seven_width, seven_height);
icons[EIGHT] = CREATE_ICON(eight_bits, eight_width, eight_height);
icons[CLOSED] = CREATE_ICON(closed_bits, closed_width, closed_height);
icons[MARKED] = CREATE_ICON(marked_bits, marked_width, marked_height);
icons[MINE] = CREATE_ICON(mine_bits, mine_width, mine_height);
icons[QUEST] = CREATE_ICON(quest_bits, quest_width, quest_height);
if (XStringListToTextProperty(&window_name, 1, &windowName) == 0) {
fprintf(stderr, "structure allocation for windowName failed\n");
exit(1);
}
if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0) {
fprintf(stderr, "structure allocation for windowName failed\n");
exit(1);
}
wm_hints.initial_state = NormalState;
wm_hints.input = True;
wm_hints.icon_pixmap = icons[MINE];
wm_hints.flags = StateHint | IconPixmapHint | InputHint;
class_hints.res_name = "XVmines";
class_hints.res_class = "Games";
XSetWMProperties(display, xv_get(frame, XV_XID), &windowName, &iconName, argv,
argc, NULL, &wm_hints, &class_hints);
timer.it_interval.tv_sec = quantum;
timer.it_interval.tv_usec = 0;
timer.it_value.tv_sec = quantum;
timer.it_value.tv_usec = 0;
init();
window_fit(frame);
xv_main_loop(frame);
}
void
canvas_repaint_proc()
{
XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
}
#ifdef __STDC__
void
canvas_event_proc(Xv_Window window, Event * event)
#else
void
canvas_event_proc(window, event)
Xv_Window window;
Event *event;
#endif
{
int x, y, which;
cell *aux;
#ifdef DEBUG
printf("Mines to go %d,checks %d closed %d\n", mines_2_go, checks, closed_tiles);
#endif
if (!playing)
return;
switch (event_xevent(event)->type) {
case ButtonRelease:
get_cell(event_xevent(event)->xbutton.x, event_xevent(event)->xbutton.y,
&x, &y);
if (first) {
place_tiles(width * height, mines, x * width + y);
xv_set(opt, PANEL_INACTIVE, TRUE, NULL);
print_string("Time->> 0:0", TIME_X, TIME_Y, CLEAR_YES);
first = FALSE;
}
switch (event_xevent(event)->xbutton.button) {
case Button1:
if (open_tile(x, y)) {
XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
}
if (mines_2_go == 0 && closed_tiles == mines)
finish(" Successful");
break;
case Button2:
aux = Cells + x * width + y;
if (aux->out_state != QUEST && aux->out_state != CLOSED)
break;
which = (aux->out_state == CLOSED) ? QUEST : CLOSED;
PLACE_ICON(icons[which], x * IC_WIDTH,
y * IC_HEIGHT);
aux->out_state = which;
XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
break;
case Button3:
if (mark_tile(x, y)) {
XCopyArea(display, pmap, dr_win, def_gc, 0, 0,
width * IC_WIDTH, height * IC_HEIGHT, 0, 0);
}
if (mines_2_go == 0 && closed_tiles == mines)
finish(" Successful");
break;
}
break;
case EnterNotify:
notify_set_itimer_func(canvas, active_func, ITIMER_REAL, &timer, NULL);
break;
case LeaveNotify:
notify_set_itimer_func(canvas, NOTIFY_FUNC_NULL, ITIMER_REAL, &timer, NULL);
break;
default:
break;
}
}
quit_proc()
{
int result;
result = notice_prompt(panel1, NULL,
NOTICE_MESSAGE_STRINGS,
"Really Quit?",
"Press YES to confirm",
"Press NO to cancel",
NULL,
NOTICE_BUTTON_YES, "YES",
NOTICE_BUTTON_NO, "NO",
NULL);
switch (result) {
case NOTICE_YES:
exit(0);
break;
case NOTICE_NO:
break;
case NOTICE_FAILED:
default:
break;
}
}
#ifdef __STDC__
int
adj_mine_num(Panel_item item, Event * event)
#else
int
adj_mine_num(item, event)
Panel_item item;
Event *event;
#endif
{
mines = atoi((char *) xv_get(item, PANEL_VALUE));
xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
if (mines > width * height || mines <= 0) {
fprintf(stderr, "xvmines: Invalid number of mines specified, using defaults\n");
if (NUM_MINES < width * height)
mines = NUM_MINES;
else
mines = width;
}
sprintf(buff, "Mines: %d\n", mines);
xv_set(frame, FRAME_LEFT_FOOTER, buff, NULL);
init();
}
#ifdef __STDC__
int
adj_size(Panel_item item, Event * event)
#else
int
adj_size(item, event)
Panel_item item;
Event *event;
#endif
{
int frame_height, n;
n = sscanf((char *) xv_get(item, PANEL_VALUE), "%dx%d", &width, &height);
xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
if (n != 2 || width <= 0 || width > MAX_WIDTH || height <= 0 || height > MAX_HEIGHT) {
fprintf(stderr, "xvmines: Invalid dimensions specified,using defaults\n");
width = HORIZ_CELLS;
height = VERT_CELLS;
}
XFreePixmap(display, pmap);
pmap = XCreatePixmap(display, dr_win, IC_WIDTH * width,
IC_HEIGHT * height, DefaultDepth(display, screen));
frame_height = height * IC_HEIGHT + xv_get(panel1, XV_HEIGHT) +
xv_get(msg_canvas, XV_HEIGHT);
xv_set(frame, XV_WIDTH, width * IC_WIDTH,
XV_HEIGHT, frame_height,
NULL);
xv_set(canvas, XV_WIDTH, width * IC_WIDTH,
XV_HEIGHT, height * IC_HEIGHT,
NULL);
free(Cells);
Cells = (cell *) malloc(width * height * sizeof(cell));
if (Cells == NULL) {
fprintf(stderr, "xvmines: malloc failed\n");
exit(1);
}
init();
}
int
restart()
{
init();
xv_set(opt, PANEL_INACTIVE, FALSE, NULL);
}
#ifdef __STDC__
int
hide_cmd_frame(Panel_item item, Event * event)
#else
int
hide_cmd_frame(item, event)
Panel_item item;
Event *event;
#endif
{
xv_set((Frame) xv_get(item, PANEL_CLIENT_DATA), XV_SHOW, FALSE, NULL);
}
#ifdef __STDC__
int
show_cmd_frame(Menu menu, Menu_item item)
#else
int
show_cmd_frame(menu, item)
Menu menu;
Menu_item item;
#endif
{
xv_set((Frame) xv_get(item, XV_KEY_DATA, KEY), XV_SHOW, TRUE, NULL);
}
#ifdef __STDC__
Frame
create_cmd_frame(Frame parent, char *msg, int (*notifier) ())
#else
Frame
create_cmd_frame(parent, msg, notifier)
Frame parent;
char *msg;
int (*notifier) ();
#endif
{
Frame popup;
Panel aux_pan;
popup = xv_create(parent, FRAME_CMD,
FRAME_LABEL, "prompt",
XV_WIDTH, 250,
XV_HEIGHT, 60,
XV_X, (int) xv_get(parent, XV_X),
XV_Y, (int) xv_get(parent, XV_Y),
NULL);
aux_pan = (Panel) xv_get(popup, FRAME_CMD_PANEL);
xv_set(aux_pan, PANEL_LAYOUT, PANEL_VERTICAL, NULL);
xv_create(aux_pan, PANEL_TEXT,
PANEL_LABEL_STRING, msg,
PANEL_VALUE_DISPLAY_LENGTH, 5,
PANEL_VALUE_STORED_LENGTH, 5,
PANEL_CLIENT_DATA, popup,
PANEL_NOTIFY_PROC, notifier,
NULL);
xv_create(aux_pan, PANEL_BUTTON,
PANEL_LABEL_STRING, "Cancel",
PANEL_CLIENT_DATA, popup,
PANEL_NOTIFY_PROC, hide_cmd_frame,
NULL);
return popup;
}
#ifdef __STDC__
void
print_string(char *to_print, int x, int y, int clr)
#else
void
print_string(to_print, x, y, clr)
char *to_print;
int x, y, clr;
#endif
{
static XFontStruct *t_font = NULL;
static int letter_width;
static int letter_height;
static Window win;
XTextItem text;
if (t_font == NULL) {
t_font = XQueryFont(display, XLoadFont(display, T_FONT_NAME));
if (t_font == NULL) {
fprintf(stderr,
"xvmines: Failed to load font %s\n", T_FONT_NAME);
exit(1);
}
letter_width = t_font->max_bounds.rbearing - t_font->min_bounds.lbearing;
letter_height = t_font->max_bounds.ascent + t_font->max_bounds.descent;
win = (Window) xv_get(canvas_paint_window(msg_canvas), XV_XID);
}
text.chars = to_print;
text.nchars = strlen(to_print);
text.delta = 0;
text.font = t_font->fid;
if (clr == CLEAR_YES)
XClearWindow(display, win);
XDrawText(display, win, def_gc, x, y, &text, 1);
}